﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing.Imaging;
using System.IO;
using PromoServer.Library.Entities;
using PromoServer.Library.BLL;
using PromoServer.Library;

namespace PromoServer_WPF.Views
{
    /// <summary>
    /// Interaction logic for LayoutView.xaml
    /// </summary>
    public partial class ImageLayoutView : UserControl
    {
        private PSLayout psLayout;
        private LayoutContent currentLayout;
        private bool isNewLayout = true;
        private BitmapImage currentBmpImg;
        private MemoryStream currentMemStream;
        private MemoryStream currentDataMemStream;
        private string newImageFilePath = string.Empty;
        private bool displayingNewImage = false;

        public ImageLayoutView(LayoutContent layout, bool isNew)
        {
            InitializeComponent();

            psLayout = new PSLayout();

            isNewLayout = isNew;

            currentLayout = layout;

            if (currentLayout.ContentFileName != string.Empty && currentLayout.ContentFileName != null)
                DisplayImage(layout.ContentFileName);

            this.DataContext = currentLayout;
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
        }

        private void DropImage(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Note that you can have more than one file.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

                // If file is valid image file, add image to image box
                if (isImageValid(files[0]))
                    DisplayTempImage(files[0]);
                else
                    MessageBox.Show("This is not a valid image file.", "Invalid File", MessageBoxButton.OK, MessageBoxImage.Stop);
            }
        }

        private bool isImageValid(string filePath)
        {
            FileInfo fi = new FileInfo(filePath);
            if (fi.Extension.ToLower() == ".jpg" || fi.Extension.ToLower() == ".jpeg" || fi.Extension.ToLower() == ".gif" || fi.Extension.ToLower() == ".bmp" || fi.Extension.ToLower() == ".png" || fi.Extension.ToLower() == ".tif" || fi.Extension.ToLower() == ".tiff")
                return true;
            else
                return false;
        }

        private string SaveImageFile(string imageFilePath)
        {
            try
            {
                FileInfo fi = new FileInfo(imageFilePath);
                string newFilePath = string.Empty;
                newFilePath = System.AppDomain.CurrentDomain.BaseDirectory;
                newFilePath += Properties.Settings.Default.Images_Directory;

                // If images directory does not exist, create it
                if (!Directory.Exists(newFilePath))
                    Directory.CreateDirectory(newFilePath);

                string newFileName = Guid.NewGuid().ToString() + fi.Extension.ToLower();
                
                newFilePath += newFileName;

                File.Copy(imageFilePath, newFilePath);

                return newFilePath;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("LayoutView.SaveImageFile", ex.Message, true);

                // Display error to user
                MessageBox.Show("Unable to save image. Error: " + ex.Message);

                return string.Empty;
            }
        }

        private string SaveTempImageFile(string imageFilePath)
        {
            try
            {
                FileInfo fi = new FileInfo(imageFilePath);
                string newFilePath = string.Empty;
                newFilePath = System.AppDomain.CurrentDomain.BaseDirectory;
                newFilePath += Properties.Settings.Default.Images_Directory;

                // If images directory does not exist, create it
                if (!Directory.Exists(newFilePath))
                    Directory.CreateDirectory(newFilePath);

                string newFileName = "tmp_" + Guid.NewGuid().ToString() + fi.Extension.ToLower();

                newFilePath += newFileName;

                File.Copy(imageFilePath, newFilePath);

                return newFilePath;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("LayoutView.SaveTempImageFile", ex.Message, true);

                // Display error to user
                MessageBox.Show("Unable to save temporary image. Error: " + ex.Message);

                return string.Empty;
            }
        }

        #region BASE64IMAGE_DEPRECATED
        private void LoadBase64Image(string base64Image)
        {
            try
            {
                byte[] binaryData = Convert.FromBase64String(base64Image);

                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.StreamSource = new MemoryStream(binaryData);
                bi.EndInit();
                previewImage.Source = bi;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("LayoutView.LoadBase64Image", ex.Message, true);

                // Display error to user
                MessageBox.Show("Unable to load image. Error: " + ex.Message);
            }
        }
        #endregion

        private void DisplayImage(string imageFilePath)
        {
            try
            {
                // Hide canvas & label
                canvas1.Visibility = Visibility.Hidden;
                imageLabel.Visibility = Visibility.Hidden;

                // Get bites from image file
                byte[] imageBytes = File.ReadAllBytes(imageFilePath);
                byte[] data = imageBytes;

                currentDataMemStream = new MemoryStream();
                currentDataMemStream.Write(data, 0, data.Length);
                currentDataMemStream.Position = 0;
                System.Drawing.Image img = System.Drawing.Image.FromStream(currentDataMemStream);

                currentBmpImg = new BitmapImage();

                currentBmpImg.BeginInit();
                currentBmpImg.CacheOption = BitmapCacheOption.Default;
                currentMemStream = new MemoryStream();
                img.Save(currentMemStream, System.Drawing.Imaging.ImageFormat.Bmp);
                currentMemStream.Seek(0, SeekOrigin.Begin);
                currentBmpImg.StreamSource = currentMemStream;
                currentBmpImg.EndInit();

                previewImage.Source = currentBmpImg;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("LayoutView.DisplayImage", ex.Message, true);

                // Display error to user
                MessageBox.Show("Unable to load image. Error: " + ex.Message);
            }
        }

        private void DisplayTempImage(string imageFilePath)
        {
            try
            {
                // Copy image to temporary file & save global path value for currently displayed image
                newImageFilePath = SaveTempImageFile(imageFilePath);

                // Hide canvas & label
                canvas1.Visibility = Visibility.Hidden;
                imageLabel.Visibility = Visibility.Hidden;

                // Get bites from image file
                byte[] imageBytes = File.ReadAllBytes(newImageFilePath);
                byte[] data = imageBytes;

                currentDataMemStream = new MemoryStream();
                currentDataMemStream.Write(data, 0, data.Length);
                currentDataMemStream.Position = 0;
                System.Drawing.Image img = System.Drawing.Image.FromStream(currentDataMemStream);

                currentBmpImg = new BitmapImage();

                currentBmpImg.BeginInit();
                currentBmpImg.CacheOption = BitmapCacheOption.Default;
                currentMemStream = new MemoryStream();
                img.Save(currentMemStream, System.Drawing.Imaging.ImageFormat.Bmp);
                currentMemStream.Seek(0, SeekOrigin.Begin);
                currentBmpImg.StreamSource = currentMemStream;
                currentBmpImg.EndInit();

                previewImage.Source = currentBmpImg;

                // Set new image flag to true
                displayingNewImage = true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("LayoutView.DisplayTempImage", ex.Message, true);

                // Display error to user
                MessageBox.Show("Unable to load image. Error: " + ex.Message);
            }
        }

        private void DisplayImage2(string imageFilePath)
        {
            try
            {
                // Hide canvas & label
                canvas1.Visibility = Visibility.Hidden;
                imageLabel.Visibility = Visibility.Hidden;

                // Get bites from image file
                byte[] imageBytes = File.ReadAllBytes(imageFilePath);
                MemoryStream ms = new MemoryStream(imageBytes);

                currentBmpImg = new BitmapImage();
                currentBmpImg.BeginInit();
                currentBmpImg.StreamSource = ms;
                currentBmpImg.EndInit();
                //currentBmpImg.Freeze();

                previewImage.Source = currentBmpImg;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("LayoutView.DisplayImage", ex.Message, true);

                // Display error to user
                MessageBox.Show("Unable to load image. Error: " + ex.Message);
            }
        }

        private void UnloadImage()
        {
            try
            {
                previewImage.Source = null;

                currentBmpImg.StreamSource = null;
                currentBmpImg.UriSource = null;

                currentMemStream.Close();
                currentDataMemStream.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void imageFileButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.Filter = "Image files|*.jpg;*.jpeg;*.bmp;*.gif;*.png;*.tif";

            // If user clicks open
            if (dlg.ShowDialog() == true)
            {
                // Load image to screen
                DisplayTempImage(dlg.FileName);
            }
        }

        public void saveLayout(int layoutID)
        {
            try
            {
                // If image was updated, delete current & save new image
                if (displayingNewImage && newImageFilePath != string.Empty)
                {
                    // Copy new image to images directory
                    string newSavedImagePath = SaveImageFile(newImageFilePath);

                    // Get current image path to be deleted
                    string deleteImagePath = currentLayout.ContentFileName;
                    
                    // Get database path to delete original image if cropped
                    string dbImagePath = psLayout.GetLayoutContentFileName(currentLayout.ID);
                    
                    // Update the current layout image file path
                    currentLayout.ContentFileName = newSavedImagePath;

                    // Delete original image, if one exists
                    if (File.Exists(deleteImagePath))
                        File.Delete(deleteImagePath);

                    // Delete database image, if different due to cropping
                    if (dbImagePath != deleteImagePath)
                    {
                        if (File.Exists(dbImagePath))
                            File.Delete(dbImagePath);
                    }

                    displayingNewImage = false;
                }

                // Save current layouts content
                if (currentLayout.LayoutID == 0)
                    currentLayout.LayoutID = layoutID;

                if (isNewLayout)
                {
                    // Add new layout
                    psLayout.SaveLayoutContent(currentLayout);

                    // Set new layout flag to false
                    isNewLayout = false;
                }
                else
                {
                    // Update existing layout
                    psLayout.SaveLayoutContent(currentLayout);
                }
            }
            catch (Exception ex)
            {
                // Display error to user
                MessageBox.Show("Failed to save layout. Error: " + ex.Message);
            }
        }

        private void deleteLayout()
        {
            try
            {
                // Delete current layout
                if (isNewLayout)
                {
                    // Remove layout view from stack panel
                    StackPanel mainStackPanel = (StackPanel)this.Parent;
                    mainStackPanel.Children.Remove(this);
                }
                else
                {
                    // Delete existing layout
                    if (psLayout.DeleteLayoutContent(currentLayout))
                    {
                        // If delete successful, remove layout from stack panel and delete image file
                        
                        // Remove layout view from stack panel
                        StackPanel mainStackPanel = (StackPanel)this.Parent;
                        mainStackPanel.Children.Remove(this);

                        // Get current image path to be deleted
                        string deleteImagePath = currentLayout.ContentFileName;

                        // Delete original image, if exists
                        if (File.Exists(deleteImagePath))
                            File.Delete(deleteImagePath);
                    }
                }
            }
            catch (Exception ex)
            {
                // Display error to user
                MessageBox.Show("Failed to delete layout. Error: " + ex.Message);
            }
        }

        private void deleteButton_Click(object sender, RoutedEventArgs e)
        {
            deleteLayout();
        }

        private void orderUpButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                sequenceTextBox.Text = Convert.ToString(Convert.ToInt32(sequenceTextBox.Text) + 1);
                currentLayout.Sequence += 1;
            }
            catch (Exception ex)
            {
                // Display error to user
                MessageBox.Show(ex.Message);
            }
        }

        private void orderDownButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (Convert.ToInt32(sequenceTextBox.Text) - 1 > 0)
                {
                    sequenceTextBox.Text = Convert.ToString(Convert.ToInt32(sequenceTextBox.Text) - 1);
                    currentLayout.Sequence -= 1;
                }
            }
            catch (Exception ex)
            {
                // Display error to user
                MessageBox.Show(ex.Message);
            }
        }

        private void durationUpButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string durationTextBoxValue = string.Empty;

                if (durationTextBox.Text == "Forever")
                    durationTextBoxValue = "0";
                else
                    durationTextBoxValue = durationTextBox.Text;

                durationTextBox.Text = Convert.ToString(Convert.ToInt32(durationTextBoxValue) + 1);
                currentLayout.Duration += 1;
            }
            catch (Exception ex)
            {
                // Display error to user
                MessageBox.Show(ex.Message);
            }
        }

        private void durationDownButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string durationTextBoxValue = string.Empty;

                if (durationTextBox.Text == "Forever")
                    durationTextBoxValue = "0";
                else
                    durationTextBoxValue = durationTextBox.Text;

                if (Convert.ToInt32(durationTextBoxValue) - 1 > 0)
                {
                    durationTextBox.Text = Convert.ToString(Convert.ToInt32(durationTextBoxValue) - 1);
                    currentLayout.Duration -= 1;
                }
                else if (Convert.ToInt32(durationTextBoxValue) - 1 == 0)
                {
                    durationTextBox.Text = "Forever";
                    currentLayout.Duration -= 1;
                }
            }
            catch (Exception ex)
            {
                // Display error to user
                MessageBox.Show(ex.Message);
            }
        }

        private void previewImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                // Save image file path before cropping
                string beforeCropImagePath = currentLayout.ContentFileName;

                // Release image for possible overwrite
                UnloadImage();

                // Show crop window
                if (displayingNewImage)
                {
                    // If image is new and not yet saved, pass in temp image file path
                    ImageCropperWindow imageCropperWindow = new ImageCropperWindow(currentLayout, newImageFilePath);
                    imageCropperWindow.ShowDialog();

                    // Reload image (If image changed, show cropped image else show original temp image)
                    if (beforeCropImagePath != currentLayout.ContentFileName)
                    {
                        // If layout was displaying new unsaved image, set the path to the cropped image
                        newImageFilePath = currentLayout.ContentFileName;

                        DisplayImage(currentLayout.ContentFileName);
                    }
                    else
                        DisplayImage(newImageFilePath);
                }
                else
                {
                    // If image is saved, pass in current layout object
                    ImageCropperWindow imageCropperWindow = new ImageCropperWindow(currentLayout);
                    imageCropperWindow.ShowDialog();

                    // Reload image
                    DisplayImage(currentLayout.ContentFileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
